﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UtilZ.Dotnet.Ex.Model;
using UtilZ.Dotnet.Ex.ZLog;

namespace UtilZ.Dotnet.Ex.Communication.Net.Web
{
    /// <summary>
    /// API中间件
    /// </summary>
    public partial class ApiMiddleware : MiddlewareAbs
    {
        /// <summary>
        /// 固定url的api方法集合[key:http-method;value:[key:url;value:Delegate]]
        /// </summary>
        private readonly Dictionary<string, Dictionary<string, Delegate>> _apiMethodDic = new Dictionary<string, Dictionary<string, Delegate>>();



        /// <summary>
        /// 构造函数
        /// </summary>
        public ApiMiddleware()
            : base()
        {

        }






        /// <summary>
        /// 映射get
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapGet(string url, Delegate mapDelegate)
        {
            this.CheckMapParameter(url, mapDelegate);
            this.PrimitiveMap(HttpRequestMethods.GET, url, mapDelegate);
        }

        /// <summary>
        /// 映射post
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapPost(string url, Delegate mapDelegate)
        {
            this.CheckMapParameter(url, mapDelegate);
            this.PrimitiveMap(HttpRequestMethods.POST, url, mapDelegate);
        }

        /// <summary>
        /// 映射put
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapPut(string url, Delegate mapDelegate)
        {
            this.CheckMapParameter(url, mapDelegate);
            this.PrimitiveMap(HttpRequestMethods.PUT, url, mapDelegate);
        }

        /// <summary>
        /// 映射delete
        /// </summary>
        /// <param name="url">url</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapDelete(string url, Delegate mapDelegate)
        {
            this.CheckMapParameter(url, mapDelegate);
            this.PrimitiveMap(HttpRequestMethods.DELETE, url, mapDelegate);
        }

        /// <summary>
        /// 映射Extension
        /// </summary>
        /// <param name="url">url模板</param>
        /// <param name="mapDelegate">匹配url模板的处理委托</param>
        public void MapExtension(string url, Delegate mapDelegate)
        {
            this.CheckMapParameter(url, mapDelegate);
            this.PrimitiveMap(HttpRequestMethods.EXTENSION_MOTHED, url, mapDelegate);
        }




        private void PrimitiveMap(string method, string url, Delegate mapDelegate)
        {
            Dictionary<string, Delegate> dic;
            if (this._apiMethodDic.TryGetValue(method, out dic))
            {
                dic = new Dictionary<string, Delegate>();
                this._apiMethodDic.Add(method, dic);
            }

            dic[url] = mapDelegate;
        }

        private void CheckMapParameter(string template, Delegate mapDelegate)
        {
            if (string.IsNullOrWhiteSpace(template))
            {
                throw new ArgumentNullException(nameof(template));
            }

            if (mapDelegate == null)
            {
                throw new ArgumentNullException(nameof(mapDelegate));
            }
        }






        /// <summary>
        /// 尝试调用中间件处理[已处理返回true,否则返回false]
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response">http响应</param>
        /// <returns>已处理返回true,否则返回false</returns>
        protected override bool PrimitiveTryInvoke(HttpRequest request, out IHttpResponse response)
        {
            response = null;

            //固定url-api处理
            Dictionary<string, Delegate> methodDic;
            if ((request.QueryStringParams == null || request.QueryStringParams.Count == 0) &&
                this._apiMethodDic.TryGetValue(request.Method, out methodDic))
            {
                //通过url直接找到处理方法后，直接调用
                Delegate apiMethod;
                if (methodDic.TryGetValue(request.Url, out apiMethod))
                {
                    response = (IHttpResponse)apiMethod.DynamicInvoke(request);
                    if (response != null)
                    {
                        return true;
                    }
                }
            }

            return false;
        }



        /// <summary>
        /// 获取所有api列表
        /// </summary>
        /// <returns></returns>
        public string GetAllApiList()
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendLine("固定url-api\r\n");
            string splitLine = new string('=', 60);

            //[key:http-method;value:[key:url;value:APIMethodInfo]]
            foreach (KeyValuePair<string, Dictionary<string, Delegate>> kv in this._apiMethodDic)
            {
                sb.AppendLine(splitLine);
                sb.Append("http请求类型:");
                sb.AppendLine(kv.Key);
                sb.AppendLine();
            }

            return sb.ToString();
        }

    }
}
